package com.hksj.app.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hksj.common.config.utils.SpringContextUtil;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ObjectUtils;

import javax.websocket.Session;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class WebsocketConnectionHolder {

    private static final Map<String, Session> container = new ConcurrentHashMap<>();

    private static final Map<String,Boolean> statusMap = new ConcurrentHashMap<>();

    private static ObjectMapper objectMapper;

    private static ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public static void addSession(String key,Session session) {
        container.put(key, session);
        statusMap.put(key, Boolean.TRUE);
    }

    public static void removeSession(String key) {
        container.remove(key);
        statusMap.remove(key);
    }

    public static Session getSession(String key) {
        return container.get(key);
    }

    public static String toObjString(Object obj){
        String result = null;
        try {
            if (ObjectUtils.isEmpty(objectMapper)){
                objectMapper = SpringContextUtil.getBean(ObjectMapper.class);
            }
            result = objectMapper.writeValueAsString(obj);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    public static void sendMessageOtherAll(String key, WebsocketResponse response){
        List<String> keyList = new ArrayList<>();
        for (String str : container.keySet()) {
            if (!Objects.equals(key,str)){
                keyList.add(str);
            }
        }
        sendMessage(keyList, toObjString(response));
    }

    public static void sendMessage(String key, WebsocketResponse response){
        sendMessage(Arrays.asList(key), toObjString(response));
    }

    public static void sendMessage(String key, String message){
        sendMessage(Arrays.asList(key), message);
    }

    public static void sendMessage(List<String> keyList, String message){
        try {
            for (String key : keyList) {
                if (key == null) continue;

                Session session = container.get(key);
                if (session != null && session.isOpen()) {
                    int retryCount = 0;
                    final int MAX_RETRIES = 5;
                    long sleepTime = 100; // 初始等待时间（ms）

                    while (retryCount < MAX_RETRIES) {
                        if (statusMap.replace(key, true, false)) {
                            try {
                                session.getAsyncRemote().sendText(message, result -> {statusMap.put(key, true);});
                                break;
                            } catch (Exception e) {
                                e.printStackTrace();
                                statusMap.put(key, true);
                                retryCount++;
                            }
                        } else {
                            try {
                                Thread.sleep(sleepTime);
                                sleepTime = Math.min(sleepTime * 2, 2000); // 指数退避，最多 2000ms
                            } catch (InterruptedException ie) {
                                Thread.currentThread().interrupt();
                                ie.printStackTrace();
                                break;
                            }
                            retryCount++;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    public static void sendMessage(List<String> keyList, String message){
//        if (threadPoolTaskExecutor == null) {
//            synchronized (WebsocketConnectionHolder.class) {
//                if (threadPoolTaskExecutor == null) {
//                    threadPoolTaskExecutor = SpringContextUtil.getBean(ThreadPoolTaskExecutor.class);
//                }
//            }
//        }
//
//        threadPoolTaskExecutor.execute(() -> {
//            try {
//                for (String key : keyList) {
//                    if (key == null) continue;
//
//                    Session session = container.get(key);
//                    if (session != null && session.isOpen()) {
//                        int retryCount = 0;
//                        final int MAX_RETRIES = 5;
//                        long sleepTime = 100; // 初始等待时间（ms）
//
//                        while (retryCount < MAX_RETRIES) {
//                            if (statusMap.replace(key, true, false)) {
//                                try {
//                                    session.getAsyncRemote().sendText(message, result -> {statusMap.put(key, true);});
//                                    break;
//                                } catch (Exception e) {
//                                    e.printStackTrace();
//                                    statusMap.put(key, true);
//                                    retryCount++;
//                                }
//                            } else {
//                                try {
//                                    Thread.sleep(sleepTime);
//                                    sleepTime = Math.min(sleepTime * 2, 2000); // 指数退避，最多 2000ms
//                                } catch (InterruptedException ie) {
//                                    Thread.currentThread().interrupt();
//                                    ie.printStackTrace();
//                                    break;
//                                }
//                                retryCount++;
//                            }
//                        }
//                    }
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        });
//    }
}
